<!--
 * @Author: anxia.ack anchenkai@come-future.com
 * @Date: 2025-04-05 16:24:03
 * @LastEditors: anxia.ack anchenkai@come-future.com
 * @LastEditTime: 2025-04-20 20:59:18
 * @FilePath: /free-learning/src/views/course/index.vue
-->
<script setup lang="ts">
import CourseTour from "./tour.vue";
import Editor from "@/components/WangEditor/index.vue";
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox, FormRules } from "element-plus";
import {
  getCourseList,
  addCourse,
  updateCourse,
  deleteCourse,
  postSendCourse,
  postRecommendCourse,
} from "@/api/course/course-mange";
import type { CourseInfo, CourseListVO, CourseListParams } from "@/api/course/course-mange/type";
import { CourseStatus } from "@/api/course/course-mange/type";
import { getList } from "@/api/system/course-category";
import type { CourseCategoryListVO } from "@/api/system/course-category/type";
import UserAPI from "@/api/system/user";
import { useUserStore } from "@/store/modules/user";
import router from "@/router";
import { title } from "process";
import { CourseAudit, CourseAuditPageVO } from "@/api/course/course-audit/type";
import { getCourseAuditHistory } from "@/api/course/course-audit";
import tourConfig from "@/utils/tourConfig";
import { mockCourseHistory, mockData } from "./mock";
defineOptions({
  name: "Course",
});
const userStore = useUserStore();
// 表格数据
const tableData = ref<CourseListVO[]>([]);
const loading = ref(false);
const total = ref(0);

// 分页参数
const pagination = reactive({
  pageNum: 1,
  pageSize: 10,
});

// 搜索条件
const searchForm = reactive<CourseListParams>({
  keywords: "",
  status: undefined as any,
  categoryId: undefined as any,
  consultantId: undefined as any,
  startBeginTime: "",
  startAfterTime: "",
  pageNum: 1,
  pageSize: 10,
});

// 课程分类选项
const categoryOptions = ref<CourseCategoryListVO[]>([]);

// 课程状态选项
const statusOptions = [
  { label: "全部", value: undefined },
  { label: "待审核", value: CourseStatus.PendingReview },
  { label: "审核通过", value: CourseStatus.Approved },
  { label: "审核未通过", value: CourseStatus.Rejected },
  { label: "已发布", value: CourseStatus.Published },
];

// 对话框控制
const dialogVisible = ref(false);
const courseContentDialogVisible = ref(false);
const step = ref(1);
const dialogTitle = ref("");
const formData = ref<Partial<CourseInfo>>({
  title: "",
  description: "",
  categoryId: undefined,
  consultantId: undefined,
  consultantName: "",
  coverImage: "",
  content: "",
  status: CourseStatus.PendingReview,
  startTime: undefined,
});

// 获取课程列表
const fetchData = async () => {
  loading.value = true;
  try {
    const params: CourseListParams = {
      pageNum: pagination.pageNum,
      pageSize: pagination.pageSize,
    };

    // 只添加非空值的查询参数
    if (searchForm.keywords) {
      params.keywords = searchForm.keywords;
    }
    if (searchForm.status !== undefined) {
      params.status = searchForm.status;
    }
    if (searchForm.categoryId !== undefined) {
      params.categoryId = searchForm.categoryId;
    }
    if (searchForm.consultantId !== undefined) {
      params.consultantId = searchForm.consultantId;
    }
    if (searchForm.startBeginTime) {
      params.startBeginTime = searchForm.startBeginTime;
    }
    if (searchForm.startAfterTime) {
      params.startAfterTime = searchForm.startAfterTime;
    }

    if (!userStore.userInfo.roles.includes("ADMIN")) {
      params.consultantId = userStore.userInfo.userId as number;
    }
    const res = await getCourseList(params);

    tableData.value = isMockData.value ? mockData : res.records;
    total.value = res.total;
  } catch (error) {
    ElMessage.error("获取课程列表失败");
  } finally {
    loading.value = false;
  }
};

// 获取课程分类
const fetchCategories = async () => {
  try {
    const res = await getList();
    categoryOptions.value = res;
  } catch (error) {
    ElMessage.error("获取课程分类失败");
  }
};

// 重置搜索条件
const resetSearch = () => {
  searchForm.keywords = "";
  searchForm.status = undefined;
  searchForm.categoryId = undefined;
  searchForm.consultantId = undefined;
  searchForm.startBeginTime = "";
  searchForm.startAfterTime = "";
  pagination.pageNum = 1;
  fetchData();
};

// 处理分页变化
const handlePageChange = (page: number) => {
  pagination.pageNum = page;
  fetchData();
};

// 处理每页条数变化
const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.pageNum = 1;
  fetchData();
};

// 打开新增/编辑对话框
const handleDialog = (row?: CourseListVO) => {
  if (row) {
    dialogTitle.value = "编辑课程";
    formData.value = { ...row };
    formData.value.coverImage = row.coverImage || "";
  } else {
    dialogTitle.value = "新增课程";
    formData.value = {
      title: "",
      description: "",
      categoryId: undefined,
      consultantId: undefined,
      consultantName: "",
      coverImage: "",
      status: CourseStatus.PendingReview,
      startTime: undefined,
    };
  }
  dialogVisible.value = true;
};

const formRef = ref<InstanceType<typeof ElForm>>();
const rules = ref<FormRules>({
  title: [{ required: true, message: "请输入课程标题", trigger: "blur" }],
  categoryId: [{ required: true, message: "请选择课程分类", trigger: "blur" }],
  status: [{ required: true, message: "请选择课程状态", trigger: "blur" }],
  startTime: [{ required: true, message: "请选择开课时间", trigger: "blur" }],
});
const submitLoading = ref(false);
// 保存数据
const handleSave = () => {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      if (step.value === 1) {
        courseContentDialogVisible.value = true;
        step.value = 2;
        return;
      }
      try {
        if (isMockData.value) {
          ElMessage.warning("当前为模拟数据，无法保存");
          return;
        }
        submitLoading.value = true;

        let name = "";
        for (const i of categoryOptions.value) {
          for (const j of i.children) {
            if (j.id === formData.value.categoryId) {
              name = j.name;
              break;
            }
          }
        }
        formData.value.categoryName = name;
        formData.value.status = CourseStatus.PendingReview;
        formData.value.isRecommend = 0;
        formData.value.consultantId = userStore.userInfo.userId as number;
        formData.value.consultantName = userStore.userInfo.nickname;
        if (formData.value.id) {
          await updateCourse(formData.value as CourseInfo);
          ElMessage.success("更新成功");
        } else {
          await addCourse(formData.value as CourseInfo);
          ElMessage.success("新增成功");
        }
        handleCancel();
        dialogVisible.value = false;
        fetchData();
      } catch (error) {
        ElMessage.error("操作失败");
      } finally {
        submitLoading.value = false;
      }
    }
  });
};
const handleTourFinish = () => {
  isMockData.value = false;
  fetchData();
};
const handleCancel = () => {
  if (step.value === 1) {
    dialogVisible.value = false;
  } else {
    courseContentDialogVisible.value = false;
    step.value = 1;
  }
  formRef.value?.resetFields();
};
// 删除数据
const handleDelete = async (row: CourseListVO) => {
  if (isMockData.value) {
    ElMessage.warning("当前为模拟数据，无法删除");
    return;
  }
  try {
    await ElMessageBox.confirm("确认删除该课程吗？", "提示", {
      type: "warning",
    });
    await deleteCourse(row.id);
    ElMessage.success("删除成功");
    fetchData();
  } catch (error) {
    if (error !== "cancel") {
      ElMessage.error("删除失败");
    }
  }
};
const handleRecommendCourse = async (row: CourseListVO) => {
  const res = await postRecommendCourse(row.id);
  if (res) {
    ElMessage.success(row.isRecommend === 1 ? "取消推荐成功" : "推荐成功");
    fetchData();
  }
};
// 获取状态标签
const getStatusTag = (status: CourseStatus) => {
  const statusMap: Record<
    CourseStatus,
    { type: "success" | "warning" | "info" | "primary" | "danger"; label: string }
  > = {
    [CourseStatus.PendingReview]: { type: "warning", label: "待审核" },
    [CourseStatus.Approved]: { type: "success", label: "审核通过" },
    [CourseStatus.Rejected]: { type: "danger", label: "审核未通过" },
    [CourseStatus.Published]: { type: "primary", label: "已发布" },
    [CourseStatus.WaitingPublish]: { type: "info", label: "待发布" },
  };
  return statusMap[status] || { type: "info", label: "未知" };
};

const consultantOptions = ref<OptionType[]>([]);
const fetchConsultantOptions = async () => {
  const res = await UserAPI.getConsultantOptions();
  consultantOptions.value = res;
};
const isMockData = ref(false);
onMounted(() => {
  const isFirstInCourse = tourConfig.getTourConfig("isFirstInCourse");
  isMockData.value =
    (isFirstInCourse === undefined ? true : isFirstInCourse) &&
    userStore.userInfo.perms.includes("sys:course:pass");
  fetchData();
  fetchCategories();
  fetchConsultantOptions();
});
const handleSendCourse = async (row: CourseListVO) => {
  if (isMockData.value) {
    ElMessage.warning("当前为模拟数据，无法发布");
    return;
  }
  const res = await postSendCourse(row.id);
  if (res) {
    if (row.status === CourseStatus.WaitingPublish) {
      ElMessage.success("发布成功");
    } else {
      ElMessage.success("下架成功");
    }
    fetchData();
  }
};
const handleCourseChapters = (row: CourseListVO) => {
  if (isMockData.value) {
    ElMessage.warning("当前为模拟数据，无法跳转");
    return;
  }
  router.push({
    path: "/course-manage/course/chapters",
    query: { courseId: row.id, title: "【" + row.title + "】课程章节" },
  });
};
const auditRecordDialogVisible = ref(false);
const courseHistory = ref<CourseAudit[]>([]);
const handleAuditRecord = async (row: CourseListVO) => {
  auditRecordDialogVisible.value = true;
  const res = await getCourseAuditHistory(row.id);
  courseHistory.value = isMockData.value ? mockCourseHistory : res;
};
// 获取状态文本
const getStatusText = (status: number) => {
  switch (status) {
    case CourseStatus.PendingReview:
      return "待审核";
    case CourseStatus.Approved:
      return "已通过";
    case CourseStatus.Rejected:
      return "已拒绝";
    default:
      return "未知";
  }
};
// 获取状态标签类型
const getStatusType = (status: number) => {
  switch (status) {
    case CourseStatus.PendingReview:
      return "warning";
    case CourseStatus.Approved:
      return "success";
    case CourseStatus.Rejected:
      return "danger";
    default:
      return "info";
  }
};
</script>

<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>课程管理</span>
          <el-button
            id="courseAdd-tour"
            v-hasPerm="['sys:course:pass']"
            type="primary"
            @click="handleDialog()"
          >
            新增课程
          </el-button>
        </div>
      </template>

      <!-- 搜索表单 -->
      <el-form id="courseSearchForm-tour" :model="searchForm" inline class="search-form">
        <el-form-item label="关键字">
          <el-input
            v-model="searchForm.keywords"
            placeholder="课程标题/描述"
            clearable
            @keyup.enter="fetchData"
          />
        </el-form-item>
        <el-form-item label="课程状态">
          <el-select
            v-model="searchForm.status"
            placeholder="请选择"
            clearable
            style="width: 150px"
          >
            <el-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-hasPerm="['sys:course:consultant_search']" label="咨询师">
          <el-select
            v-model="searchForm.consultantId"
            placeholder="请选择咨询师"
            clearable
            style="width: 150px"
          >
            <el-option
              v-for="item in consultantOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="课程分类">
          <el-cascader
            v-model="searchForm.categoryId"
            :options="categoryOptions"
            clearable
            :props="{
              value: 'id',
              label: 'name',
              children: 'children',
              emitPath: false,
              expandTrigger: 'click',
            }"
          />
        </el-form-item>
        <el-form-item label="开课时间">
          <el-date-picker
            v-model="searchForm.startBeginTime"
            type="date"
            placeholder="开始日期"
            value-format="YYYY-MM-DD"
          />
          <span class="mx-2">至</span>
          <el-date-picker
            v-model="searchForm.startAfterTime"
            type="date"
            placeholder="结束日期"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="fetchData">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>

      <!-- 表格 -->
      <el-table v-loading="loading" :data="tableData" border style="width: 100%">
        <el-table-column prop="title" label="课程标题" min-width="200" show-overflow-tooltip />
        <el-table-column prop="categoryName" label="课程分类" width="180" show-overflow-tooltip />
        <el-table-column prop="consultantName" label="咨询师" width="120" />
        <el-table-column prop="chapterNum" label="章节数" width="100" align="center" />
        <el-table-column prop="favoriteCount" label="收藏课程人数" width="120" align="center" />
        <el-table-column prop="reviewCount" label="课程评论数" width="100" align="center" />
        <el-table-column prop="likeCount" label="课程点赞数" width="100" align="center" />
        <el-table-column prop="status" label="状态" width="120" align="center">
          <template #default="{ row }">
            <el-tag :type="getStatusTag(row.status).type">
              {{ getStatusTag(row.status).label }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="startTime" label="开课时间" width="180">
          <template #default="{ row }">
            {{ row.startTime ?? "-" }}
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180">
          <template #default="{ row }">
            {{ new Date(row.createTime).toLocaleString() }}
          </template>
        </el-table-column>
        <el-table-column v-hasPerm="['sys:course:pass']" label="操作" width="380" fixed="right">
          <template #default="{ row }">
            <el-button
              id="courseAuditOperate-tour"
              type="info"
              link
              @click="handleAuditRecord(row)"
            >
              审核历史
            </el-button>
            <el-button
              v-if="
                row.status !== CourseStatus.Rejected && row.status !== CourseStatus.PendingReview
              "
              id="courseChapterOperate-tour"
              type="primary"
              link
              @click="handleCourseChapters(row)"
            >
              分集维护
            </el-button>
            <el-button id="courseEditOperate-tour" type="primary" link @click="handleDialog(row)">
              编辑
            </el-button>
            <el-button id="courseDeleteOperate-tour" type="danger" link @click="handleDelete(row)">
              删除
            </el-button>
            <el-button
              v-if="
                row.status === CourseStatus.Published || row.status === CourseStatus.WaitingPublish
              "
              id="courseSendOperate-tour"
              type="primary"
              link
              @click="handleSendCourse(row)"
            >
              {{ row.status === CourseStatus.WaitingPublish ? "发布" : "下架" }}
            </el-button>
            <el-button
              v-if="row.status === CourseStatus.Published"
              v-hasPerm="['sys:course:recommend']"
              type="primary"
              link
              @click="handleRecommendCourse(row)"
            >
              {{ row.isRecommend === 1 ? "取消推荐" : "推荐" }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.pageNum"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
      <el-form ref="formRef" :rules="rules" :model="formData" label-width="100px">
        <el-form-item label="课程标题" required prop="title">
          <el-input v-model="formData.title" placeholder="请输入课程标题" />
        </el-form-item>
        <el-form-item label="课程分类" required prop="categoryId">
          <el-cascader
            v-model="formData.categoryId"
            :options="categoryOptions"
            :props="{
              value: 'id',
              label: 'name',
              children: 'children',
              emitPath: false,
              expandTrigger: 'click',
            }"
          />
        </el-form-item>
        <el-form-item label="开课时间" required prop="startTime">
          <el-date-picker
            v-model="formData.startTime"
            type="datetime"
            placeholder="选择开课时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="课程描述" prop="description">
          <el-input
            v-model="formData.description"
            type="textarea"
            :rows="4"
            placeholder="请输入课程描述"
          />
        </el-form-item>
        <el-form-item label="封面图片">
          <ImageUpload
            v-model="formData.coverImage"
            :limit="1"
            :maxSize="2"
            :supportFileType="['jpg', 'jpeg', 'png']"
            :style="{ width: '178px', height: '100px' }"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleSave">下一步</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog v-model="courseContentDialogVisible" title="课程介绍" width="1000px">
      <div style="height: 50vh; overflow-y: scroll">
        <editor v-model="formData.content" style="z-index: 99999" />
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button v-loading="submitLoading" type="primary" @click="handleSave">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog v-model="auditRecordDialogVisible" title="审核记录" width="1000px">
      <el-timeline>
        <el-timeline-item
          v-for="item in courseHistory"
          :key="item.id"
          :type="getStatusType(item.status)"
          :timestamp="item.auditTime"
        >
          <h4>{{ getStatusText(item.status) }}</h4>
          <p>审核人：{{ item.auditorName }}</p>
          <p>审核意见：{{ item.opinion }}</p>
        </el-timeline-item>
      </el-timeline>
    </el-dialog>
    <CourseTour @finish="handleTourFinish" />
  </div>
</template>

<style lang="scss" scoped>
.app-container {
  padding: 20px;

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .search-form {
    margin-bottom: 20px;
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }

  .mx-2 {
    margin: 0 8px;
  }
}
</style>
